/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package com.farmcode.web.generation;

import com.farmcode.api.runtime.*;
import com.farmcode.api.runtime.metadata.ObjectInfo;
import com.farmcode.api.runtime.regex.MatchContext;
import com.farmcode.base.dao.DAOException;
import com.farmcode.base.manager.FacadeException;
import com.farmcode.console.api.business.custom.ExtMatchContextManager;
import com.farmcode.console.api.business.custom.ExtMatchManager;
import com.farmcode.console.api.business.custom.ExtProjectManager;
import com.farmcode.console.api.model.Match;
import com.farmcode.console.api.model.Project;
import com.farmcode.console.api.model.Property;
import com.farmcode.console.api.model.Template;
import com.farmcode.web.generation.objectinfo.ProcedureBackingBean;
import com.farmcode.web.generation.objectinfo.TablesBackingBean;
import com.farmcode.web.generation.objectinfo.ViewsBackingBean;
import com.farmcode.web.generation.propery.VariableBackingBean;
import com.farmcode.web.generation.template.TemplateBackingBean;
import java.util.ArrayList;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.ejb.EJB;
import javax.faces.bean.RequestScoped;
import javax.inject.Named;

/**
 *
 * @author Oscar Ivan Prado
 */
@Named("generateBackingBean")
@RequestScoped
public class GenerateBackingBean extends BaseCodeGenerator {
    
    public static final String PROJECT_NAME = Project.class.getName() + ".name";
    
    private String projectName;
    
    @EJB
    private ExtMatchManager extMatchManager;
    @EJB
    private ExtMatchContextManager extMatchContextManager;
    @EJB
    private RuntimeServerAPI runtimeServerAPI;
    @EJB
    private ExtProjectManager projectManager;
    
    private List<Template> templates;
    
    public String projectSelected(){
        try {
            
            showMessage("[Project Selected:"+getProjectName() + "]");
            Project project = projectManager.getProjectByName(getProjectName());
            goGenerateProject(project);
            
        } catch (DAOException ex) {
            Logger.getLogger(GeneratorBase.class.getName()).log(Level.SEVERE, null, ex);
        }
        
        return null;
    }
    
    public void onAction() {
        
       try{
           FARMCodeContext context = getContext();
           Metadata metadata = new Metadata();

           TemplateCollection collection = new TemplateCollection();
           for (Template template : getTemplates()) {
                TemplateInfo templateInfo = new TemplateInfo(template.getName(), template.getPath(), template.getPath(), template.getExtension(), template.isSelected());
                collection.add(templateInfo);
                getMathContextByTemplate(template, templateInfo);
            }

            List<ObjectInfo> tables = getSession().getValue(TablesBackingBean.OBJECTS_INFO);
            List<ObjectInfo> views = getSession().getValue(ViewsBackingBean.OBJECTS_INFO);
            List<ObjectInfo> procedures = getSession().getValue(ProcedureBackingBean.OBJECTS_INFO);

            if (tables != null && tables.size() > 0) {
                metadata.getObjectInfos().add(tables);
            }

            if (views != null && views.size() > 0) {
                metadata.getObjectInfos().add(views);
            }

            if (procedures != null && procedures.size() > 0) {
                metadata.getObjectInfos().add(procedures);
            }
            
            List<Property> variables = getSession().getValue(VariableBackingBean.VARIABLES_SESSION_NAME);
            
            if(variables != null){
                for (Property property : variables) {
                    context.put(property.getName(), property.getValue());
                }
            }
            
            context.put("project", getProject().getName());
            context.put(FARMCodeContext.TEMPLATES, collection);
            context.put(FARMCodeContext.METADATA, metadata);
            context.put(FARMCodeContext.METADATA, metadata);

            if (metadata.getObjectInfos().size() > 0) {
                    Response<?> response = runtimeServerAPI.compile(context);
                }
       }catch(RuntimeServerException ex){
           showError(ex.getMessage());
       }catch(FacadeException ex){
           showError(ex.getMessage());
       }
        
    }
    
    
     /**
     * @return the templates
     */
    public List<Template> getTemplates()  {
        templates = new ArrayList<Template>();
        if (getSession().getValue(TemplateBackingBean.TEMPLATES_SESSION_NAME) != null) {
            templates = getSession().getValue(TemplateBackingBean.TEMPLATES_SESSION_NAME);
        }
        return templates;
    }
    
     /**
     * @param templates the templates to set
     */
    public void setTemplates(List<Template> templates) {
        this.templates = templates;
        getSession().setValue(templates.getClass().getCanonicalName() + ".templates", templates);
    }
    
    private void getMathContextByTemplate(Template template, TemplateInfo templateInfo) throws FacadeException {
        List<Match> matchs = extMatchManager.getMatchByProject(getProject(), template);
        for (Match match : matchs) {
            MatchContext matchContext = new MatchContext();
            List<com.farmcode.console.api.model.MatchContext> mts = extMatchContextManager.getMatchContextByMatch(match);
            matchContext.put("prefix", match.getPrefix());
            matchContext.put("replace", match.getReplace());
            matchContext.put("relocate", match.getRelocate());
            matchContext.put("relocatePath", match.getRelocatePath());
            for (com.farmcode.console.api.model.MatchContext mt : mts) {
                matchContext.put(mt.getName(), mt.getValue());
            }
            if(matchContext != null){
                templateInfo.getMatchContextCollection().add(matchContext);
            }
            
        }
    }

    /**
     * @return the projectName
     */
    public String getProjectName() {
        if(getSession().getValue(PROJECT_NAME) != null){
            projectName = getSession().getValue(PROJECT_NAME);
        }
        return projectName;
    }

    /**
     * @param projectName the projectName to set
     */
    public void setProjectName(String projectName) {
        this.projectName = projectName;
        getSession().setValue(PROJECT_NAME, projectName);
    }
    
}
